package com.yunhe.dtu.task.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.Table;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.fastjson.JSONArray;
import com.yunhe.common.model.ResultObject;
import com.yunhe.common.util.DateTimeUtils;
import com.yunhe.common.util.StringUtil;
import com.yunhe.dtu.pojo.Data;
import com.yunhe.dtu.pojo.ExportData;
import com.yunhe.dtu.util.*;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import com.yunhe.common.util.CollectionUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @ClassName CheckDataController
 * @Description TODO
 * @Author HeTao
 * @Date 2020/12/18 12:24
 * @Version 1.0
 **/
@Api(value = "checkDataController",description = "数据校验")
@RestController
@RequestMapping(value = "/v1")
public class CheckDataController {

    private String exportPath = "classpath:mapping/export.yml";

    @RequestMapping(value = "/checkData",method = RequestMethod.GET)
    public ResponseEntity<ResultObject> checkData(@RequestParam("startPath") String  startPath,
                                                  @RequestParam("endPath") String  endPath,
                                                  HttpServletResponse response) throws InterruptedException {
        List<File> files = new ArrayList<>();
        File file1 = new File(startPath);
        File file = new File(endPath);
        files.add(file1);
        files.add(file);
        List<List<String>> strs = new ArrayList<>();
        //读取日志文件获取每一行数据
        if(!CollectionUtil.isEmpty(files)){
            for (File file2 : files) {
                try {
                    List<String> list = LogAnalysisUtils.useJavaGrok(file2);
                    strs.add(list);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        //获得数据信息
        getDataInfo(strs,response);
        return new ResponseEntity<>(new ResultObject<>(null), HttpStatus.OK);
    }


    @ApiOperation(value = "导出表计示值数据")
    @RequestMapping(value = "/exportDtuData",method = RequestMethod.GET)
    public void exportDtuData(@RequestParam("startTime") String  startTime,
                              @RequestParam("endTime") String  endTime,
                              @ApiParam(value = "园区期数",example = "B 一期 A 二期 HY 恒运 JW 金旺",required = true) @RequestParam("type") String  type,
                              HttpServletResponse response) throws InterruptedException, IOException {
        String path  = "/home/tomcat/yh-dtu/logs";
        //String path = "C:\\Users\\84795\\Desktop";
        //开始时间数据
        List<List<String>> startTimestrs = new ArrayList<>();
        String startTimeStartPath = path+"/"+startTime+"/yh-dtu-log-"+startTime+"-0.log";
        String startTimeEndPath = path+"/"+startTime+"/yh-dtu-log-"+startTime+"-1.log";
        getDataByTime(startTimeStartPath,startTimeEndPath,startTimestrs);
        //结束时间数据
        List<List<String>> endTimestrs = new ArrayList<>();
        String endTimeStartPath = path+"/"+endTime+"/yh-dtu-log-"+endTime+"-0.log";
        String endTimeEndPath = path+"/"+endTime+"/yh-dtu-log-"+endTime+"-1.log";
        getDataByTime(endTimeStartPath,endTimeEndPath,endTimestrs);
        //获得数据信息

        getDataInfo(startTimestrs,startTime,endTimestrs,endTime,type,response);
    }

    private void getDataInfo(List<List<String>> startTimestrs, String startTime,
                             List<List<String>> endTimestrs, String endTime,
                             String type,HttpServletResponse response) throws IOException {
        //开始时间数据
        List<Data> startData = getDataInfoByTime(startTimestrs, startTime+" 00:00:00");
        //结束时间数据
        List<Data> endData = getDataInfoByTime(endTimestrs, endTime+" 23:59:59");
        //比对两组数据做差值
        List<ExportData> exportDataList = getData(startData,startTime,endData,endTime,type);
        String templatePath = "/export-template.xlsx";
        InputStream templateInputStream = this.getClass().getResourceAsStream(templatePath);
        response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
        String title = "";
        switch (type){
            case "A":
                title = "二期"+startTime+"-"+endTime+"数据";
                break;
            case "B":
                title = "一期"+startTime+"-"+endTime+"数据";
                break;
            case "HY":
                title = "恒运"+startTime+"-"+endTime+"数据";
                break;
            case "JW":
                title = "金旺"+startTime+"-"+endTime+"数据";
                break;
        }
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(title+"导出.xlsx", "utf-8"));
        EasyExcel.write(response.getOutputStream(), ExportData.class).withTemplate(templateInputStream).sheet().doFill(exportDataList);
    }

    private List<ExportData> getData(List<Data> startData,String startTime, List<Data> endData, String endTime,String type) {

        List<ExportData> exportDataList = new ArrayList<>();
        Map<String, String> exportMap = YmlUtils.getYmlByFileName(exportPath, type);
        Map<String, List<Data>> map = startData.stream().collect(Collectors.groupingBy(Data::getSid));
        if(!CollectionUtil.isEmpty(exportMap)){
            Set<String> keys = exportMap.keySet();
            if(!CollectionUtil.isEmpty(keys)){
                for (Data endDatum : endData) {
                    if(keys.contains(type + "." + endDatum.getSid() + ".company_office")){
                        String values = exportMap.get(type + "." + endDatum.getSid() + ".company_office");
                        String[] split = values.split("%");
                        ExportData exportData = new ExportData();
                        exportData.setCompanyName(split[1]);
                        exportData.setOfficeName(split[0]);
                        exportData.setTableNum(split[2]);
                        exportData.setStartTime(startTime);
                        exportData.setEndTime(endTime);
                        exportData.setSid(endDatum.getSid());
                        exportData.setEndData(endDatum.getE());
                        exportData.setEndDataTime(endDatum.getUpdate_time());
                        exportData.setE_flat(endDatum.getE_flat());
                        exportData.setE_peak(endDatum.getE_peak());
                        exportData.setE_valley(endDatum.getE_valley());
                        if(!CollectionUtil.isEmpty(map)){
                            List<Data> data = map.get(endDatum.getSid());
                            if(!CollectionUtil.isEmpty(data)){
                                exportData.setStartDataTime(data.get(0).getUpdate_time());
                                exportData.setStartData(data.get(0).getE());
                                exportData.setStart_e_valley(data.get(0).getE_valley());
                                exportData.setStart_e_peak(data.get(0).getE_peak());
                                exportData.setStart_e_flat(data.get(0).getE_flat());
                            }
                        }
                        exportData.setDifference(BigDecimalUtil.sub(exportData.getEndData(),exportData.getStartData()));
                        exportDataList.add(exportData);
                    }
                }
            }
        }


        return exportDataList;
    }

    private List<Data>  getDataInfoByTime(List<List<String>> strs, String time) {
        List<Data> objects = new ArrayList<>();
        Long startTime = DateTimeUtils.getTimestamp(time, null);
        List<String> list = Arrays.asList("0f02a820", "0f02ba22", "0f02b724", "0f02bd22", "0f02a220");
        if(!CollectionUtil.isEmpty(strs)){
            for (List<String> str : strs) {
                for (String s : str) {
                    String[] split = s.split("dtu的整条数据:");
                    String s1 = split[1];
                    if(!s1.startsWith("[")){
                        s1 = "["+s1+"]";
                    }
                    List<Data> parses = JSONArray.parseArray(s1, Data.class);
                    if(!CollectionUtil.isEmpty(parses)){
                        Data data = parses.get(0);
                        if(data != null){
                            if(list.contains(data.getSid())){
                                objects.add(data);
                            }
                            else {
                                if( data.getE() == null || data.getE().compareTo(BigDecimal.ZERO)==0){
                                    data.setE(BigDecimalUtil.add(data.getE_flat(),data.getE_peak(),data.getE_valley()));
                                }
                                objects.add(data);
//                            Long endTime = DateTimeUtils.getTimestamp(update_time, null);
//                            long difference = startTime - endTime;
//                            //判断当前时间是否符合输入的时间
//                            if (time.endsWith(" 00:00:00")) {
//                                if (Math.abs(difference) <= 5 * 60 * 1000) {
//                                    if (endTime >= startTime) {
//                                        objects.add(data);
//                                    }
//                                } else if (Math.abs(difference) > 24 * 60 * 60 * 1000) {
//                                    objects.add(data);
//                                }else if (Math.abs(difference) <= 24 * 60 * 60 * 1000 && Math.abs(difference) <= 30 * 60 * 60 * 1000) {
//                                    objects.add(data);
//                                }
//                            }else if(time.endsWith(" 23:59:59")){
//                                if (Math.abs(difference) <= 5 * 60 * 1000) {
//                                    if (endTime <= startTime) {
//                                        objects.add(data);
//                                    }
//                                } else if (Math.abs(difference) > 24 * 60 * 60 * 1000) {
//                                    objects.add(data);
//                                }
//                                //objects.add(data);
//                            }
                            }
                        }

                    }
                }
            }
        }

        //List<Data> datas = objects.stream().filter(distinctByKey(Data::getSid)).collect(Collectors.toList());
        List<Data> datas = new ArrayList<>();
        Map<String, List<Data>> map = objects.stream().collect(Collectors.groupingBy(Data::getSid));
        if(!CollectionUtil.isEmpty(map)){
            for (Map.Entry<String, List<Data>> stringListEntry : map.entrySet()) {
                if(time.endsWith(" 23:59:59")){
                    String replace = time.replace(" 23:59:59", " 08:00:00");
                    Data data1 = stringListEntry.getValue().stream().min(Comparator.comparing(data -> {
                        return Math.abs(DateTimeUtils.getTimestamp(replace,null)-DateTimeUtils.getTimestamp(data.getUpdate_time(), null));
                    })).get();
                    datas.add(data1);
                }else if(time.endsWith(" 00:00:00")){
                    String replace = time.replace(" 00:00:00", " 08:00:00");
                    List<Data> dataList = new ArrayList<>();
//                    for (Data data : stringListEntry.getValue()) {
//                        String update_time = data.getUpdate_time();
//                        Long endTime = DateTimeUtils.getTimestamp(update_time, null);
//                        long difference = startTime - endTime;
//                        if(Math.abs(difference) <= 15 * 60 * 1000){
//                            if(endTime >= startTime){
//                                dataList.add(data);
//                            }
//                        }
//                    }
                    if(CollectionUtil.isEmpty(dataList)){
                        Data data1 = stringListEntry.getValue().stream().min(Comparator.comparing(data -> {
                            return Math.abs(DateTimeUtils.getTimestamp(replace,null)-DateTimeUtils.getTimestamp(data.getUpdate_time(), null));
                        })).get();
                        datas.add(data1);
                    }else {
                        Data data1 = dataList.stream().min(Comparator.comparing(data -> {
                            return Math.abs(DateTimeUtils.getTimestamp(replace,null)-DateTimeUtils.getTimestamp(data.getUpdate_time(), null));
                        })).get();
                        datas.add(data1);
                    }

                }
            }
        }
        System.out.println("当前的数据条数："+datas.size());
        return datas;
    }

    public static void main(String[] args) {
        System.out.println(DateTimeUtils.getTimestamp("2021-06-13 17:02:54", null));
    }

    private void getDataByTime(String startPath,String endPath,List<List<String>> strs){
        List<File> files = new ArrayList<>();
        File file1 = new File(startPath);
        File file = new File(endPath);
        if(file1 != null && file1.exists()){
            files.add(file1);
        }
        if(file != null && file.exists()){
            files.add(file);
        }

        //读取日志文件获取每一行数据
        if(!CollectionUtil.isEmpty(files)){
            for (File file2 : files) {
                try {
                    List<String> list = LogAnalysisUtils.useJavaGrok(file2);
                    strs.add(list);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }




    @RequestMapping(value = "/checkDataByTime",method = RequestMethod.GET)
    public void checkDataByTime(@RequestParam("startPath") String  startPath,
                                                        @RequestParam("endPath") String  endPath,
                                                        @RequestParam("time") String  time,
                                                        HttpServletResponse response) throws Exception {
        List<File> files = new ArrayList<>();
        File file1 = new File(startPath);
        File file = new File(endPath);
        files.add(file1);
        files.add(file);
        List<List<String>> strs = new ArrayList<>();
        //读取日志文件获取每一行数据
        if(!CollectionUtil.isEmpty(files)){
            for (File file2 : files) {
                try {
                    List<String> list = LogAnalysisUtils.useJavaGrok(file2);
                    strs.add(list);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        //获得数据信息
        getDataInfoByTime(strs,time,response);
    }

    private void getDataInfoByTime(List<List<String>> strs, String time, HttpServletResponse response) throws Exception {
        List<Data> objects = new ArrayList<>();
        Long startTime = DateTimeUtils.getTimestamp(time, null);
        List<String> list = Arrays.asList("0f02a820", "0f02ba22", "0f02b724", "0f02bd22", "0f02a220");
        if(!CollectionUtil.isEmpty(strs)){
            for (List<String> str : strs) {
                for (String s : str) {
                    String[] split = s.split("dtu的整条数据:");
                    String s1 = split[1];
                    if(!s1.startsWith("[")){
                        s1 = "["+s1+"]";
                    }
                    List<Data> parses = JSONArray.parseArray(s1, Data.class);
                    if(!CollectionUtil.isEmpty(parses)){
                        Data data = parses.get(0);
                        String update_time = data.getUpdate_time();
                        if(list.contains(data.getSid())){
                            objects.add(data);
                        }else {
                            Long endTime = DateTimeUtils.getTimestamp(update_time, null);
                            long difference = startTime - endTime;
                            //判断当前时间是否符合输入的时间
                            if (time.endsWith(" 00:00:00")) {
                                if (Math.abs(difference) <= 5 * 60 * 1000) {
                                    if (endTime >= startTime) {
                                        objects.add(data);
                                    }
                                } else if (Math.abs(difference) > 24 * 60 * 60 * 1000) {
                                    objects.add(data);
                                }
                            }else if(time.endsWith("23:59:59")){
                                objects.add(data);
                            }
//                            else if(Math.abs(difference) > 5*60*1000 && Math.abs(difference) <= 24*60*60*1000){
//                                if(time.endsWith(" 00:00:00")){
//                                    if(endTime >= startTime){
//                                        objects.add(data);
//                                    }
//                                }else if(time.endsWith(" 23:59:59")){
//                                    if(endTime <= startTime){
//                                        objects.add(data);
//                                    }
//                                }
//                            }
                        }
                    }
                }
            }
        }

        List<Data> datas = objects.stream().filter(distinctByKey(Data::getSid)).collect(Collectors.toList());
        System.out.println("当前的数据条数："+datas.size());
        //数据处理
//        for (Data data : datas) {
//            if(data.getE()!= null && data.getE()==0.0){
//                data.setTotalE(data.getE_flat()+data.getE_peak()+data.getE_valley());
//            }
//        }
        //写入excel
        ExcelUtils.export(datas,response,Data.class);
    }

    private void getDataInfo(List<List<String>> strs,HttpServletResponse response) {
        List<Data> objects = new ArrayList<>();
        if(!CollectionUtil.isEmpty(strs)){
            for (List<String> str : strs) {
                for (String s : str) {
                    String[] split = s.split("dtu的整条数据:");
                    String s1 = split[1];
                    if(!s1.startsWith("[")){
                        s1 = "["+s1+"]";
                    }
                    List<Data> parses = JSONArray.parseArray(s1, Data.class);
                    objects.add(parses.get(0));
                }
            }
        }
        //去重之后获得不重复的表计数据
        List<Data> datas = objects.stream().filter(distinctByKey(Data::getSid)).collect(Collectors.toList());
        System.out.println("当前的数据条数："+datas.size());
        //数据处理
//        for (Data data : datas) {
//            if(data.getE()!= null && data.getE()==0.0){
//                data.setTotalE(data.getE_flat()+data.getE_peak()+data.getE_valley());
//            }
//        }
        //写入excel
        ExcelUtils.export(datas,response,Data.class);
    }

    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object,Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
}